/*
 * Copyright 2007-2009 Perttu "celeron55" Ahola <celeron55@gmail.com>
 *
 * This file is part of jukuMagic.
 *
 * jukuMagic is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * jukuMagic is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with jukuMagic.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef MAIN_H_
#define MAIN_H_

#include <wx/wxprec.h>
#include <wx/cmdline.h>
#include <wx/wx.h>
#include <string>
#include <vector>

#include "circuit.h"
#include "board.h"

#define BWSCROLLRATE 10

using namespace std;

enum
{
	WindowID_BoardWidthScroll = 1,
	WindowID_BoardHeightScroll,
	WindowID_BoardWindow,
	WindowID_GenerateButton,
	WindowID_GenerateExactButton,
	WindowID_SetStaticButton,
	WindowID_SetMovableButton,
};

enum
{
	TimerID_BoardWindow_HilightRedraw = 1,
};

void DrawOpaqueRectangle(wxWindowDC &dc, wxPoint point, wxSize size);

class JukuApp: public wxApp
{
private:
	/*bool verbose_mode_on, fast_mode_on;
	wxString file_to_open;
	long int wanted_maxwidth;
	Board board;*/
public:
	JukuApp();
    //virtual bool OnInit();
    virtual int OnExit();
    //virtual int OnRun();
    virtual void OnInitCmdLine(wxCmdLineParser& parser);
    virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
};

static const wxCmdLineEntryDesc g_cmdLineDesc [] =
{
     { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("Help"),
			wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
     { wxCMD_LINE_SWITCH, wxT("v"), wxT("verbose"), wxT("Print irrational amounts of debug information") },
     //{ wxCMD_LINE_SWITCH, wxT("f"), wxT("fast"), wxT("Enables fast & dirty generating") },
     { wxCMD_LINE_PARAM,  wxT(""), wxT(""), wxT("filename"),
			wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
     { wxCMD_LINE_OPTION, wxT("W"), wxT("width"), wxT("Width of board"),
			wxCMD_LINE_VAL_NUMBER, wxCMD_LINE_PARAM_OPTIONAL },
     { wxCMD_LINE_OPTION, wxT("H"), wxT("height"), wxT("Height of board"),
			wxCMD_LINE_VAL_NUMBER, wxCMD_LINE_PARAM_OPTIONAL },
	 { wxCMD_LINE_SWITCH, wxT("a"), wxT("no-auto"), wxT("No auto-generate") },
     { wxCMD_LINE_NONE }
};

struct BoardWindowSettings{
	BoardWindowSettings(unsigned int blocksize_, unsigned int spacing_);
	void CalcValues(Board *board);

	unsigned int blocksize; //asetettava
	unsigned int spacing; //asetettava

	unsigned int ybordersize;
	unsigned int blockspacing;
	unsigned int wire_height;
	unsigned int wirepart_height;
	unsigned int part_edge_decrease;
	unsigned int hole_size;
	unsigned int cutwidth;
	unsigned int solder_size;
	unsigned int solderdotsize;

	unsigned int draw1startx;
	unsigned int draw1starty;

	unsigned int draw2startx;
	unsigned int draw2starty;

	unsigned int draw3startx;
	unsigned int draw3starty;

	int clientw;
	int clienth;
};

class BoardWindow: public wxScrolledWindow
{
	Board *board;
	BoardWindowSettings *settings;
	wxTimer *hilightredrawtimer;
	int mousehilightw, mousehilighth;
	int mousehilightx, mousehilighty;
	bool hilight_wanted, hilight_valid;
public:
	BoardWindow(wxWindow *parent, wxWindowID id);
	~BoardWindow();
	
	void OnPaint(wxPaintEvent& event);
	void OnLeftUp(wxMouseEvent& event);
	void OnRightUp(wxMouseEvent& event);
	void OnMotion(wxMouseEvent& event);
	void OnHilightRedrawTimer(wxTimerEvent& event);

	void SetBoard(Board *_board);
	void ReDrawBoard();
	
	Coord GetBoardCoordFromMousePos(int mx, int my);
	void SetMouseHilightSize(int w, int h);
	
	DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(BoardWindow, wxScrolledWindow)
	EVT_PAINT(BoardWindow::OnPaint)
	EVT_LEFT_UP(BoardWindow::OnLeftUp)
	EVT_RIGHT_UP(BoardWindow::OnRightUp)
	EVT_MOTION(BoardWindow::OnMotion)
	EVT_TIMER(TimerID_BoardWindow_HilightRedraw, BoardWindow::OnHilightRedrawTimer)
END_EVENT_TABLE()

enum PartListItemType{
	IT_PART,
	IT_WPART,
	IT_WIRE
};

struct PartListItemInfo
{
	PartListItemType type;
	unsigned int num;
};

class JukuFrame: public wxFrame
{
	bool verbose_mode_on;
	unsigned int boardw, boardh;
	Circuit circuit;
	wxScrollBar *boardw_scroll;
	wxScrollBar *boardh_scroll;
	wxStaticText *boardsize_statictext;
	wxCheckBox *autogenerate_check;
	Board *board;
	BoardWindow *boardwindow;
	wxListBox *partlist;
	vector<PartListItemInfo> partlistinfo;
	wxStaticText *infolabel0;
	bool waiting_static_place_selection;
	int cpartnum_waiting_static_place_selection;

	void UpdateBoardSizeText();
public:
    JukuFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
	
    void OnQuit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);
    void OnOpen(wxCommandEvent& event);
	void OnBoardWidthScroll(wxScrollEvent& event);
	void OnBoardHeightScroll(wxScrollEvent& event);
	void OnGenerateButton(wxCommandEvent& event);
	//void OnGenerateExactButton(wxCommandEvent& event);
	void OnSetStaticButton(wxCommandEvent& event);
	void OnSetMovableButton(wxCommandEvent& event);
	void OnBWLeftClick(wxCommandEvent& event);
	void OnBWRightClick(wxCommandEvent& event);
	
	bool CmdLine(wxCmdLineParser &parser);
	bool OpenFile(wxString filename);
	bool ReGenerateBoard();
	void RefreshBoardInfo();
	int GetCircuitPartNumFromPartListSelection();
	
    DECLARE_EVENT_TABLE()
};

enum
{
    ID_Quit = 1,
    ID_About,
	ID_Open,
};

DECLARE_EVENT_TYPE(wxEVT_BWLEFTCLICK, -1)
DEFINE_EVENT_TYPE(wxEVT_BWLEFTCLICK)

DECLARE_EVENT_TYPE(wxEVT_BWRIGHTCLICK, -1)
DEFINE_EVENT_TYPE(wxEVT_BWRIGHTCLICK)

BEGIN_EVENT_TABLE(JukuFrame, wxFrame)
    EVT_MENU(ID_Quit, JukuFrame::OnQuit)
    EVT_MENU(ID_About, JukuFrame::OnAbout)
    EVT_MENU(ID_Open, JukuFrame::OnOpen)
    EVT_BUTTON(WindowID_SetStaticButton, JukuFrame::OnSetStaticButton)
    EVT_BUTTON(WindowID_SetMovableButton, JukuFrame::OnSetMovableButton)
	EVT_COMMAND_SCROLL(WindowID_BoardWidthScroll, JukuFrame::OnBoardWidthScroll)
	EVT_COMMAND_SCROLL(WindowID_BoardHeightScroll, JukuFrame::OnBoardHeightScroll)
	EVT_BUTTON(WindowID_GenerateButton, JukuFrame::OnGenerateButton)
	//EVT_BUTTON(WindowID_GenerateExactButton, JukuFrame::OnGenerateExactButton)
	EVT_COMMAND(WindowID_BoardWindow, wxEVT_BWLEFTCLICK, JukuFrame::OnBWLeftClick)
	EVT_COMMAND(WindowID_BoardWindow, wxEVT_BWRIGHTCLICK, JukuFrame::OnBWRightClick)
END_EVENT_TABLE()

DECLARE_APP(JukuApp)

#endif

